#pragma once
#ifndef AUTO_JSON_H
#define AUTO_JSON_H

#ifdef __cplusplus

#include "cJSON.h"
#include <string>

extern "C"
{
    typedef enum
    {
        OBJ_JSON,
        ARRAY_JSON,
        STRING_JSON,
        NUMBER_JSON,
        BOOL_JSON,
        NULL_JSON,
    } json_type_t;

    class AutoJson
    {
    private:
        cJSON *root;

        bool is_this_obj_son = false;
        // son operators
        cJSON *father = nullptr;
        json_type_t father_type = json_type_t::NULL_JSON;
        std::string self_key;
        uint8_t self_index_in_father_array = 0;
        AutoJson(cJSON *const root, cJSON *const father, const std::string &self_key, json_type_t father_type);
        AutoJson(cJSON *const root, cJSON *const father, uint8_t self_index_in_father_array, json_type_t father_type);

    public:
        AutoJson(json_type_t type = json_type_t::OBJ_JSON);
        AutoJson(const std::string &json);
        AutoJson(const char *json);

        std::string asString();
        int asInt();
        bool asBool();
        double asDouble();

        // AutoJson son(const std::string &key);
        AutoJson operator[](const std::string &key);

        AutoJson operator[](uint8_t index);
        void operator=(const char *value);
        void operator=(const std::string &value);
        void operator=(int value);
        void operator=(bool value);
        void operator=(double value);

        void del(const std::string &key);
        void del(uint8_t index);

        AutoJson addArray(const std::string &key);

        // void addItem(const std::string &key, const char *value);
        // void addItem(const std::string &key, const std::string &value);
        // void addItem(const std::string &key, int value);
        // void addItem(const std::string &key, bool value);
        // void addItem(const std::string &key, double value);

        // void addElement(const char *value);
        // void addElement(const std::string &value);
        // void addElement(int value);
        // void addElement(bool value);
        // void addElement(double value);
        // void addElement(const std::string &key, const char *value);
        // void addElement(const std::string &key, const std::string &value);
        // void addElement(const std::string &key, int value);
        // void addElement(const std::string &key, bool value);
        // void addElement(const std::string &key, double value);

        // void setItem(const std::string &key, const char *value);
        // void setItem(const std::string &key, const std::string &value);
        // void setItem(const std::string &key, int value);
        // void setItem(const std::string &key, bool value);
        // void setItem(const std::string &key, double value);

        void setVal(const char *value);
        void setVal(const std::string &value);
        void setVal(int value);
        void setVal(bool value);
        void setVal(double value);

        std::string print();

        ~AutoJson();
    };
}

#endif
#endif